/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * vim: set ts=8 sts=4 et sw=4 tw=99: * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */#ifndef jit_shared_Lowering_shared_inl_h#define jit_shared_Lowering_shared_inl_h#include"jit/shared/Lowering-shared.h"#include"jit/MIR.h"#include"jit/MIRGenerator.h"namespacejs{namespacejit{voidLIRGeneratorShared::emitAtUses(MInstruction*mir){MOZ_ASSERT(mir->canEmitAtUses());mir->setEmittedAtUses();mir->setVirtualRegister(0);}LUseLIRGeneratorShared::use(MDefinition*mir,LUsepolicy){// It is illegal to call use() on an instruction with two defs.#if BOX_PIECES > 1MOZ_ASSERT(mir->type()!=MIRType::Value);#endif#if INT64_PIECES > 1MOZ_ASSERT(mir->type()!=MIRType::Int64);#endifensureDefined(mir);policy.setVirtualRegister(mir->virtualRegister());returnpolicy;}template<size_tX>voidLIRGeneratorShared::define(details::LInstructionFixedDefsTempsHelper<1,X>*lir,MDefinition*mir,LDefinition::Policypolicy){LDefinition::Typetype=LDefinition::TypeFrom(mir->type());define(lir,mir,LDefinition(type,policy));}template<size_tX>voidLIRGeneratorShared::define(details::LInstructionFixedDefsTempsHelper<1,X>*lir,MDefinition*mir,constLDefinition&def){// Call instructions should use defineReturn.MOZ_ASSERT(!lir->isCall());uint32_tvreg=getVirtualRegister();// Assign the definition and a virtual register. Then, propagate this// virtual register to the MIR, so we can map MIR to LIR during lowering.lir->setDef(0,def);lir->getDef(0)->setVirtualRegister(vreg);lir->setMir(mir);mir->setVirtualRegister(vreg);add(lir);}template<size_tX,size_tY>voidLIRGeneratorShared::defineFixed(LInstructionHelper<1,X,Y>*lir,MDefinition*mir,constLAllocation&output){LDefinition::Typetype=LDefinition::TypeFrom(mir->type());LDefinitiondef(type,LDefinition::FIXED);def.setOutput(output);define(lir,mir,def);}template<size_tOps,size_tTemps>voidLIRGeneratorShared::defineInt64Fixed(LInstructionHelper<INT64_PIECES,Ops,Temps>*lir,MDefinition*mir,constLInt64Allocation&output){uint32_tvreg=getVirtualRegister();#if JS_BITS_PER_WORD == 64LDefinitiondef(LDefinition::GENERAL,LDefinition::FIXED);def.setOutput(output.value());lir->setDef(0,def);lir->getDef(0)->setVirtualRegister(vreg);#elseLDefinitiondef0(LDefinition::GENERAL,LDefinition::FIXED);def0.setOutput(output.low());lir->setDef(0,def0);lir->getDef(0)->setVirtualRegister(vreg);getVirtualRegister();LDefinitiondef1(LDefinition::GENERAL,LDefinition::FIXED);def1.setOutput(output.high());lir->setDef(1,def1);lir->getDef(1)->setVirtualRegister(vreg+1);#endiflir->setMir(mir);mir->setVirtualRegister(vreg);add(lir);}template<size_tOps,size_tTemps>voidLIRGeneratorShared::defineReuseInput(LInstructionHelper<1,Ops,Temps>*lir,MDefinition*mir,uint32_toperand){// Note: Any other operand that is not the same as this operand should be// marked as not being "atStart". The regalloc cannot handle those and can// overwrite the inputs!// The input should be used at the start of the instruction, to avoid moves.MOZ_ASSERT(lir->getOperand(operand)->toUse()->usedAtStart());LDefinition::Typetype=LDefinition::TypeFrom(mir->type());LDefinitiondef(type,LDefinition::MUST_REUSE_INPUT);def.setReusedInput(operand);define(lir,mir,def);}template<size_tOps,size_tTemps>voidLIRGeneratorShared::defineInt64ReuseInput(LInstructionHelper<INT64_PIECES,Ops,Temps>*lir,MDefinition*mir,uint32_toperand){// Note: Any other operand that is not the same as this operand should be// marked as not being "atStart". The regalloc cannot handle those and can// overwrite the inputs!// The input should be used at the start of the instruction, to avoid moves.MOZ_ASSERT(lir->getOperand(operand)->toUse()->usedAtStart());#if JS_BITS_PER_WORD == 32MOZ_ASSERT(lir->getOperand(operand+1)->toUse()->usedAtStart());#endifMOZ_ASSERT(!lir->isCall());uint32_tvreg=getVirtualRegister();LDefinitiondef1(LDefinition::GENERAL,LDefinition::MUST_REUSE_INPUT);def1.setReusedInput(operand);lir->setDef(0,def1);lir->getDef(0)->setVirtualRegister(vreg);#if JS_BITS_PER_WORD == 32getVirtualRegister();LDefinitiondef2(LDefinition::GENERAL,LDefinition::MUST_REUSE_INPUT);def2.setReusedInput(operand+1);lir->setDef(1,def2);lir->getDef(1)->setVirtualRegister(vreg+1);#endiflir->setMir(mir);mir->setVirtualRegister(vreg);add(lir);}template<size_tOps,size_tTemps>voidLIRGeneratorShared::defineBox(LInstructionHelper<BOX_PIECES,Ops,Temps>*lir,MDefinition*mir,LDefinition::Policypolicy){// Call instructions should use defineReturn.MOZ_ASSERT(!lir->isCall());MOZ_ASSERT(mir->type()==MIRType::Value);uint32_tvreg=getVirtualRegister();#if defined(JS_NUNBOX32)lir->setDef(0,LDefinition(vreg+VREG_TYPE_OFFSET,LDefinition::TYPE,policy));lir->setDef(1,LDefinition(vreg+VREG_DATA_OFFSET,LDefinition::PAYLOAD,policy));getVirtualRegister();#elif defined(JS_PUNBOX64)lir->setDef(0,LDefinition(vreg,LDefinition::BOX,policy));#endiflir->setMir(mir);mir->setVirtualRegister(vreg);add(lir);}template<size_tOps,size_tTemps>voidLIRGeneratorShared::defineInt64(LInstructionHelper<INT64_PIECES,Ops,Temps>*lir,MDefinition*mir,LDefinition::Policypolicy){// Call instructions should use defineReturn.MOZ_ASSERT(!lir->isCall());MOZ_ASSERT(mir->type()==MIRType::Int64);uint32_tvreg=getVirtualRegister();#if JS_BITS_PER_WORD == 32lir->setDef(0,LDefinition(vreg+INT64LOW_INDEX,LDefinition::GENERAL,policy));lir->setDef(1,LDefinition(vreg+INT64HIGH_INDEX,LDefinition::GENERAL,policy));getVirtualRegister();#elselir->setDef(0,LDefinition(vreg,LDefinition::GENERAL,policy));#endiflir->setMir(mir);mir->setVirtualRegister(vreg);add(lir);}voidLIRGeneratorShared::defineSharedStubReturn(LInstruction*lir,MDefinition*mir){lir->setMir(mir);MOZ_ASSERT(lir->isBinarySharedStub()||lir->isUnarySharedStub()||lir->isNullarySharedStub());MOZ_ASSERT(mir->type()==MIRType::Value);uint32_tvreg=getVirtualRegister();#if defined(JS_NUNBOX32)lir->setDef(TYPE_INDEX,LDefinition(vreg+VREG_TYPE_OFFSET,LDefinition::TYPE,LGeneralReg(JSReturnReg_Type)));lir->setDef(PAYLOAD_INDEX,LDefinition(vreg+VREG_DATA_OFFSET,LDefinition::PAYLOAD,LGeneralReg(JSReturnReg_Data)));getVirtualRegister();#elif defined(JS_PUNBOX64)lir->setDef(0,LDefinition(vreg,LDefinition::BOX,LGeneralReg(JSReturnReg)));#endifmir->setVirtualRegister(vreg);add(lir);}voidLIRGeneratorShared::defineReturn(LInstruction*lir,MDefinition*mir){lir->setMir(mir);MOZ_ASSERT(lir->isCall());gen->setNeedsStaticStackAlignment();uint32_tvreg=getVirtualRegister();switch(mir->type()){caseMIRType::Value:#if defined(JS_NUNBOX32)lir->setDef(TYPE_INDEX,LDefinition(vreg+VREG_TYPE_OFFSET,LDefinition::TYPE,LGeneralReg(JSReturnReg_Type)));lir->setDef(PAYLOAD_INDEX,LDefinition(vreg+VREG_DATA_OFFSET,LDefinition::PAYLOAD,LGeneralReg(JSReturnReg_Data)));getVirtualRegister();#elif defined(JS_PUNBOX64)lir->setDef(0,LDefinition(vreg,LDefinition::BOX,LGeneralReg(JSReturnReg)));#endifbreak;caseMIRType::Int64:#if defined(JS_NUNBOX32)lir->setDef(INT64LOW_INDEX,LDefinition(vreg+INT64LOW_INDEX,LDefinition::GENERAL,LGeneralReg(ReturnReg64.low)));lir->setDef(INT64HIGH_INDEX,LDefinition(vreg+INT64HIGH_INDEX,LDefinition::GENERAL,LGeneralReg(ReturnReg64.high)));getVirtualRegister();#elif defined(JS_PUNBOX64)lir->setDef(0,LDefinition(vreg,LDefinition::GENERAL,LGeneralReg(ReturnReg)));#endifbreak;caseMIRType::Float32:lir->setDef(0,LDefinition(vreg,LDefinition::FLOAT32,LFloatReg(ReturnFloat32Reg)));break;caseMIRType::Double:lir->setDef(0,LDefinition(vreg,LDefinition::DOUBLE,LFloatReg(ReturnDoubleReg)));break;caseMIRType::Int8x16:caseMIRType::Int16x8:caseMIRType::Int32x4:caseMIRType::Bool8x16:caseMIRType::Bool16x8:caseMIRType::Bool32x4:lir->setDef(0,LDefinition(vreg,LDefinition::SIMD128INT,LFloatReg(ReturnSimd128Reg)));break;caseMIRType::Float32x4:lir->setDef(0,LDefinition(vreg,LDefinition::SIMD128FLOAT,LFloatReg(ReturnSimd128Reg)));break;default:LDefinition::Typetype=LDefinition::TypeFrom(mir->type());MOZ_ASSERT(type!=LDefinition::DOUBLE&&type!=LDefinition::FLOAT32);lir->setDef(0,LDefinition(vreg,type,LGeneralReg(ReturnReg)));break;}mir->setVirtualRegister(vreg);add(lir);}template<size_tOps,size_tTemps>voidLIRGeneratorShared::defineSinCos(LInstructionHelper<2,Ops,Temps>*lir,MDefinition*mir,LDefinition::Policypolicy){MOZ_ASSERT(lir->isCall());uint32_tvreg=getVirtualRegister();lir->setDef(0,LDefinition(vreg,LDefinition::DOUBLE,LFloatReg(ReturnDoubleReg)));#if defined(JS_CODEGEN_ARM)lir->setDef(1,LDefinition(vreg+VREG_INCREMENT,LDefinition::DOUBLE,LFloatReg(FloatRegister(FloatRegisters::d1,FloatRegister::Double))));#elif defined(JS_CODEGEN_ARM64)lir->setDef(1,LDefinition(vreg+VREG_INCREMENT,LDefinition::DOUBLE,LFloatReg(FloatRegister(FloatRegisters::d1,FloatRegisters::Double))));#elif defined(JS_CODEGEN_MIPS32) || defined(JS_CODEGEN_MIPS64)lir->setDef(1,LDefinition(vreg+VREG_INCREMENT,LDefinition::DOUBLE,LFloatReg(f2)));#elif defined(JS_CODEGEN_NONE)MOZ_CRASH();#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)lir->setDef(1,LDefinition(vreg+VREG_INCREMENT,LDefinition::DOUBLE,LFloatReg(xmm1)));#else#error "Unsupported architecture for SinCos"#endifgetVirtualRegister();lir->setMir(mir);mir->setVirtualRegister(vreg);add(lir);return;}// In LIR, we treat booleans and integers as the same low-level type (INTEGER).// When snapshotting, we recover the actual JS type from MIR. This function// checks that when making redefinitions, we don't accidentally coerce two// incompatible types.staticinlineboolIsCompatibleLIRCoercion(MIRTypeto,MIRTypefrom){if(to==from)returntrue;if((to==MIRType::Int32||to==MIRType::Boolean)&&(from==MIRType::Int32||from==MIRType::Boolean)){returntrue;}// SIMD types can be coerced with from*Bits operators.if(IsSimdType(to)&&IsSimdType(from))returntrue;returnfalse;}// We can redefine the sin(x) and cos(x) function to return the sincos result.voidLIRGeneratorShared::redefine(MDefinition*def,MDefinition*as,MMathFunction::Functionfunc){MOZ_ASSERT(def->isMathFunction());MOZ_ASSERT(def->type()==MIRType::Double&&as->type()==MIRType::SinCosDouble);MOZ_ASSERT(MMathFunction::Sin==func||MMathFunction::Cos==func);ensureDefined(as);MMathFunction*math=def->toMathFunction();MOZ_ASSERT(math->function()==MMathFunction::Cos||math->function()==MMathFunction::Sin);// The sincos returns two values:// - VREG: it returns the sin's value of the sincos;// - VREG + VREG_INCREMENT: it returns the cos' value of the sincos.if(math->function()==MMathFunction::Sin)def->setVirtualRegister(as->virtualRegister());elsedef->setVirtualRegister(as->virtualRegister()+VREG_INCREMENT);}voidLIRGeneratorShared::redefine(MDefinition*def,MDefinition*as){MOZ_ASSERT(IsCompatibleLIRCoercion(def->type(),as->type()));// Try to emit MIR marked as emitted-at-uses at, well, uses. For// snapshotting reasons we delay the MIRTypes match, or when we are// coercing between bool and int32 constants.if(as->isEmittedAtUses()&&(def->type()==as->type()||(as->isConstant()&&(def->type()==MIRType::Int32||def->type()==MIRType::Boolean)&&(as->type()==MIRType::Int32||as->type()==MIRType::Boolean)))){MInstruction*replacement;if(def->type()!=as->type()){if(as->type()==MIRType::Int32)replacement=MConstant::New(alloc(),BooleanValue(as->toConstant()->toInt32()));elsereplacement=MConstant::New(alloc(),Int32Value(as->toConstant()->toBoolean()));def->block()->insertBefore(def->toInstruction(),replacement);emitAtUses(replacement->toInstruction());}else{replacement=as->toInstruction();}def->replaceAllUsesWith(replacement);}else{ensureDefined(as);def->setVirtualRegister(as->virtualRegister());#ifdef DEBUGif(JitOptions.runExtraChecks&&def->resultTypeSet()&&as->resultTypeSet()&&!def->resultTypeSet()->equals(as->resultTypeSet())){switch(def->type()){caseMIRType::Object:caseMIRType::ObjectOrNull:caseMIRType::String:caseMIRType::Symbol:{LAssertResultT*check=new(alloc())LAssertResultT(useRegister(def));add(check,def->toInstruction());break;}caseMIRType::Value:{LAssertResultV*check=new(alloc())LAssertResultV(useBox(def));add(check,def->toInstruction());break;}default:break;}}#endif}}voidLIRGeneratorShared::ensureDefined(MDefinition*mir){if(mir->isEmittedAtUses()){mir->toInstruction()->accept(this);MOZ_ASSERT(mir->isLowered());}}LUseLIRGeneratorShared::useRegister(MDefinition*mir){returnuse(mir,LUse(LUse::REGISTER));}LUseLIRGeneratorShared::useRegisterAtStart(MDefinition*mir){returnuse(mir,LUse(LUse::REGISTER,true));}LUseLIRGeneratorShared::use(MDefinition*mir){returnuse(mir,LUse(LUse::ANY));}LUseLIRGeneratorShared::useAtStart(MDefinition*mir){returnuse(mir,LUse(LUse::ANY,true));}LAllocationLIRGeneratorShared::useOrConstant(MDefinition*mir){if(mir->isConstant())returnLAllocation(mir->toConstant());returnuse(mir);}LAllocationLIRGeneratorShared::useOrConstantAtStart(MDefinition*mir){if(mir->isConstant())returnLAllocation(mir->toConstant());returnuseAtStart(mir);}LAllocationLIRGeneratorShared::useRegisterOrConstant(MDefinition*mir){if(mir->isConstant())returnLAllocation(mir->toConstant());returnuseRegister(mir);}LAllocationLIRGeneratorShared::useRegisterOrConstantAtStart(MDefinition*mir){if(mir->isConstant())returnLAllocation(mir->toConstant());returnuseRegisterAtStart(mir);}LAllocationLIRGeneratorShared::useRegisterOrZero(MDefinition*mir){if(mir->isConstant()&&mir->toConstant()->isInt32(0))returnLAllocation();returnuseRegister(mir);}LAllocationLIRGeneratorShared::useRegisterOrZeroAtStart(MDefinition*mir){if(mir->isConstant()&&mir->toConstant()->isInt32(0))returnLAllocation();returnuseRegisterAtStart(mir);}LAllocationLIRGeneratorShared::useRegisterOrNonDoubleConstant(MDefinition*mir){if(mir->isConstant()&&mir->type()!=MIRType::Double&&mir->type()!=MIRType::Float32)returnLAllocation(mir->toConstant());returnuseRegister(mir);}#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)LAllocationLIRGeneratorShared::useAnyOrConstant(MDefinition*mir){returnuseRegisterOrConstant(mir);}LAllocationLIRGeneratorShared::useStorable(MDefinition*mir){returnuseRegister(mir);}LAllocationLIRGeneratorShared::useStorableAtStart(MDefinition*mir){returnuseRegisterAtStart(mir);}LAllocationLIRGeneratorShared::useAny(MDefinition*mir){returnuseRegister(mir);}#elseLAllocationLIRGeneratorShared::useAnyOrConstant(MDefinition*mir){returnuseOrConstant(mir);}LAllocationLIRGeneratorShared::useAny(MDefinition*mir){returnuse(mir);}LAllocationLIRGeneratorShared::useStorable(MDefinition*mir){returnuseRegisterOrConstant(mir);}LAllocationLIRGeneratorShared::useStorableAtStart(MDefinition*mir){returnuseRegisterOrConstantAtStart(mir);}#endifLAllocationLIRGeneratorShared::useKeepalive(MDefinition*mir){returnuse(mir,LUse(LUse::KEEPALIVE));}LAllocationLIRGeneratorShared::useKeepaliveOrConstant(MDefinition*mir){if(mir->isConstant())returnLAllocation(mir->toConstant());returnuseKeepalive(mir);}LUseLIRGeneratorShared::useFixed(MDefinition*mir,Registerreg){returnuse(mir,LUse(reg));}LUseLIRGeneratorShared::useFixedAtStart(MDefinition*mir,Registerreg){returnuse(mir,LUse(reg,true));}LUseLIRGeneratorShared::useFixed(MDefinition*mir,FloatRegisterreg){returnuse(mir,LUse(reg));}LUseLIRGeneratorShared::useFixed(MDefinition*mir,AnyRegisterreg){returnreg.isFloat()?use(mir,LUse(reg.fpu())):use(mir,LUse(reg.gpr()));}LUseLIRGeneratorShared::useFixedAtStart(MDefinition*mir,AnyRegisterreg){returnreg.isFloat()?use(mir,LUse(reg.fpu(),true)):use(mir,LUse(reg.gpr(),true));}LDefinitionLIRGeneratorShared::temp(LDefinition::Typetype,LDefinition::Policypolicy){returnLDefinition(getVirtualRegister(),type,policy);}LInt64DefinitionLIRGeneratorShared::tempInt64(LDefinition::Policypolicy){#if JS_BITS_PER_WORD == 32LDefinitionhigh=temp(LDefinition::GENERAL,policy);LDefinitionlow=temp(LDefinition::GENERAL,policy);returnLInt64Definition(high,low);#elsereturnLInt64Definition(temp(LDefinition::GENERAL,policy));#endif}LDefinitionLIRGeneratorShared::tempFixed(Registerreg){LDefinitiont=temp(LDefinition::GENERAL);t.setOutput(LGeneralReg(reg));returnt;}LDefinitionLIRGeneratorShared::tempFloat32(){returntemp(LDefinition::FLOAT32);}LDefinitionLIRGeneratorShared::tempDouble(){returntemp(LDefinition::DOUBLE);}LDefinitionLIRGeneratorShared::tempCopy(MDefinition*input,uint32_treusedInput){MOZ_ASSERT(input->virtualRegister());LDefinitiont=temp(LDefinition::TypeFrom(input->type()),LDefinition::MUST_REUSE_INPUT);t.setReusedInput(reusedInput);returnt;}template<typenameT>voidLIRGeneratorShared::annotate(T*ins){ins->setId(lirGraph_.getInstructionId());}template<typenameT>voidLIRGeneratorShared::add(T*ins,MInstruction*mir){MOZ_ASSERT(!ins->isPhi());current->add(ins);if(mir){MOZ_ASSERT(current==mir->block()->lir());ins->setMir(mir);}annotate(ins);}#ifdef JS_NUNBOX32// Returns the virtual register of a js::Value-defining instruction. This is// abstracted because MBox is a special value-returning instruction that// redefines its input payload if its input is not constant. Therefore, it is// illegal to request a box's payload by adding VREG_DATA_OFFSET to its raw id.staticinlineuint32_tVirtualRegisterOfPayload(MDefinition*mir){if(mir->isBox()){MDefinition*inner=mir->toBox()->getOperand(0);if(!inner->isConstant()&&inner->type()!=MIRType::Double&&inner->type()!=MIRType::Float32)returninner->virtualRegister();}if(mir->isTypeBarrier())returnVirtualRegisterOfPayload(mir->getOperand(0));returnmir->virtualRegister()+VREG_DATA_OFFSET;}// Note: always call ensureDefined before calling useType/usePayload,// so that emitted-at-use operands are handled correctly.LUseLIRGeneratorShared::useType(MDefinition*mir,LUse::Policypolicy){MOZ_ASSERT(mir->type()==MIRType::Value);returnLUse(mir->virtualRegister()+VREG_TYPE_OFFSET,policy);}LUseLIRGeneratorShared::usePayload(MDefinition*mir,LUse::Policypolicy){MOZ_ASSERT(mir->type()==MIRType::Value);returnLUse(VirtualRegisterOfPayload(mir),policy);}LUseLIRGeneratorShared::usePayloadAtStart(MDefinition*mir,LUse::Policypolicy){MOZ_ASSERT(mir->type()==MIRType::Value);returnLUse(VirtualRegisterOfPayload(mir),policy,true);}LUseLIRGeneratorShared::usePayloadInRegisterAtStart(MDefinition*mir){returnusePayloadAtStart(mir,LUse::REGISTER);}voidLIRGeneratorShared::fillBoxUses(LInstruction*lir,size_tn,MDefinition*mir){ensureDefined(mir);lir->getOperand(n)->toUse()->setVirtualRegister(mir->virtualRegister()+VREG_TYPE_OFFSET);lir->getOperand(n+1)->toUse()->setVirtualRegister(VirtualRegisterOfPayload(mir));}#endifLUseLIRGeneratorShared::useRegisterForTypedLoad(MDefinition*mir,MIRTypetype){MOZ_ASSERT(type!=MIRType::Value&&type!=MIRType::None);MOZ_ASSERT(mir->type()==MIRType::Object||mir->type()==MIRType::Slots);#ifdef JS_PUNBOX64// On x64, masm.loadUnboxedValue emits slightly less efficient code when// the input and output use the same register and we're not loading an// int32/bool/double, so we just call useRegister in this case.if(type!=MIRType::Int32&&type!=MIRType::Boolean&&type!=MIRType::Double)returnuseRegister(mir);#endifreturnuseRegisterAtStart(mir);}LBoxAllocationLIRGeneratorShared::useBox(MDefinition*mir,LUse::Policypolicy,booluseAtStart){MOZ_ASSERT(mir->type()==MIRType::Value);ensureDefined(mir);#if defined(JS_NUNBOX32)returnLBoxAllocation(LUse(mir->virtualRegister(),policy,useAtStart),LUse(VirtualRegisterOfPayload(mir),policy,useAtStart));#elsereturnLBoxAllocation(LUse(mir->virtualRegister(),policy,useAtStart));#endif}LBoxAllocationLIRGeneratorShared::useBoxOrTyped(MDefinition*mir){if(mir->type()==MIRType::Value)returnuseBox(mir);#if defined(JS_NUNBOX32)returnLBoxAllocation(useRegister(mir),LAllocation());#elsereturnLBoxAllocation(useRegister(mir));#endif}LBoxAllocationLIRGeneratorShared::useBoxOrTypedOrConstant(MDefinition*mir,booluseConstant){if(useConstant&&mir->isConstant()){#if defined(JS_NUNBOX32)returnLBoxAllocation(LAllocation(mir->toConstant()),LAllocation());#elsereturnLBoxAllocation(LAllocation(mir->toConstant()));#endif}returnuseBoxOrTyped(mir);}LInt64AllocationLIRGeneratorShared::useInt64(MDefinition*mir,LUse::Policypolicy,booluseAtStart){MOZ_ASSERT(mir->type()==MIRType::Int64);ensureDefined(mir);uint32_tvreg=mir->virtualRegister();#if JS_BITS_PER_WORD == 32returnLInt64Allocation(LUse(vreg+INT64HIGH_INDEX,policy,useAtStart),LUse(vreg+INT64LOW_INDEX,policy,useAtStart));#elsereturnLInt64Allocation(LUse(vreg,policy,useAtStart));#endif}LInt64AllocationLIRGeneratorShared::useInt64Fixed(MDefinition*mir,Register64regs,booluseAtStart){MOZ_ASSERT(mir->type()==MIRType::Int64);ensureDefined(mir);uint32_tvreg=mir->virtualRegister();#if JS_BITS_PER_WORD == 32returnLInt64Allocation(LUse(regs.high,vreg+INT64HIGH_INDEX,useAtStart),LUse(regs.low,vreg+INT64LOW_INDEX,useAtStart));#elsereturnLInt64Allocation(LUse(regs.reg,vreg,useAtStart));#endif}LInt64AllocationLIRGeneratorShared::useInt64FixedAtStart(MDefinition*mir,Register64regs){returnuseInt64Fixed(mir,regs,true);}LInt64AllocationLIRGeneratorShared::useInt64(MDefinition*mir,booluseAtStart){// On 32-bit platforms, always load the value in registers.#if JS_BITS_PER_WORD == 32returnuseInt64(mir,LUse::REGISTER,useAtStart);#elsereturnuseInt64(mir,LUse::ANY,useAtStart);#endif}LInt64AllocationLIRGeneratorShared::useInt64AtStart(MDefinition*mir){returnuseInt64(mir,/* useAtStart = */true);}LInt64AllocationLIRGeneratorShared::useInt64Register(MDefinition*mir,booluseAtStart){returnuseInt64(mir,LUse::REGISTER,useAtStart);}LInt64AllocationLIRGeneratorShared::useInt64OrConstant(MDefinition*mir,booluseAtStart){if(mir->isConstant()){#if defined(JS_NUNBOX32)returnLInt64Allocation(LAllocation(mir->toConstant()),LAllocation());#elsereturnLInt64Allocation(LAllocation(mir->toConstant()));#endif}returnuseInt64(mir,useAtStart);}LInt64AllocationLIRGeneratorShared::useInt64RegisterOrConstant(MDefinition*mir,booluseAtStart){if(mir->isConstant()){#if defined(JS_NUNBOX32)returnLInt64Allocation(LAllocation(mir->toConstant()),LAllocation());#elsereturnLInt64Allocation(LAllocation(mir->toConstant()));#endif}returnuseInt64Register(mir,useAtStart);}}// namespace jit}// namespace js#endif /* jit_shared_Lowering_shared_inl_h */